/**
 * Copyright 2011, Under-Ground Studio.
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.edu.zju.vlis.aus.service;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import cn.edu.zju.vlis.aus.R;
import cn.edu.zju.vlis.aus.SplashActivity;
import cn.edu.zju.vlis.aus.db.UsageRecordDAO;

/**
 * Instance of this class is a service running in background. This service will
 * connect to logcat event logs, analyze the logs and store the result to
 * database. This service also support bind, to let activities set its
 * properties.
 * 
 * @author ymsong (songyuming1985@gmail.com) 2011-7-19
 */
public class LogcatAnalyzeService extends Service {
	// do analysis every 10 minutes
	private static final int INTERVAL = 10 * 60 * 1000;

	// instance count (either 0 or 1)
	public static int instanceCount;

	private UsageRecordDAO dao;
	// runnable to run the analysis.
	private LogcatAnalyzer worker;
	private LogcatAnalyzeRunnable backgroundAnalyzer;
	private Thread backgroundThead;
	// the binder to support activity binding.
	private IBinder binder = new LogcatAnalyzeBinder();

	@Override
	public void onCreate() {
		dao = new UsageRecordDAO(this);
		worker = new LogcatAnalyzer(dao);
		backgroundAnalyzer = new LogcatAnalyzeRunnable();

	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		if (instanceCount > 0) {
			throw new IllegalStateException("The service is already running.");
		}
		backgroundThead = new Thread(backgroundAnalyzer,
				"Logcat_Analyze_Service");
		backgroundThead.start();
//		showNotification();
		instanceCount++;
		return START_STICKY;
	}

	/**
	 * show notification when service started.
	 */
	protected void showNotification() {
		CharSequence startText = getText(R.string.service_started);
		Notification notification = new Notification(R.drawable.icon,
				startText, System.currentTimeMillis());
		PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
				new Intent(this, SplashActivity.class), 0);
		CharSequence runningText = getText(R.string.service_running);
		CharSequence descText = getText(R.string.service_description);
		notification.setLatestEventInfo(this, runningText, descText,
				contentIntent);
		startForeground(R.string.service_started, notification);
	}

	@Override
	public IBinder onBind(Intent intent) {
		return binder;
	}

	@Override
	public void onDestroy() {
		instanceCount--;
		dao.close();
	}

	/**
	 * Return the interval time between two analysis.
	 * 
	 * @return the interval in millisecond.
	 */
	public int getInterval() {
		return INTERVAL;
	}

	/**
	 * Request the service to stop. This method will not cause the service to
	 * stop immediately.
	 */
	public void requestStop() {
		backgroundThead.interrupt();
//		stopForeground(true);
	}

	/**
	 * The runnable run in a separate thread to perform the work.
	 */
	private class LogcatAnalyzeRunnable implements Runnable {
		
		private int times;

		@Override
		public void run() {
			while (true) {
				times++;
				Log.i("LogcatAnalyzeService", "Service is running analysis for "+ times +" times");
				worker.analyze(LogcatAnalyzeService.this);
				if (!Thread.interrupted()) {
					try {
						Thread.sleep(INTERVAL);
					} catch (InterruptedException e) {
						break;
					}
				} else {
					break;
				}
			}
			stopSelf();
		}
	}

	/**
	 * The binder to support communication between activities.
	 */
	public class LogcatAnalyzeBinder extends Binder {
		public LogcatAnalyzeService getService() {
			return LogcatAnalyzeService.this;
		}
	}
}
